﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using MyLocalChurch.Constants;
using MyLocalChurch.Models;
using MyLocalChurch.Models.KidsChurch;

namespace MyLocalChurch.Business
{
    public static class BarcodeManager
    {
        public static Barcode GenerateBarcode(MyContext context, string securityCode = null)
        {
            var randomizer = new Random();
            string code;

            var barcodes = context.Barcodes.ToList();

            if (string.IsNullOrEmpty(securityCode))
                securityCode = GenerateSecurityBarcode(context);

            while (true)
            {
                code = string.Format(BarcodeConstants.Format,
                                     randomizer.Next(BarcodeConstants.PartMin,
                                                     BarcodeConstants.PartMax)
                                               .ToString(),
                                     securityCode);

                if (barcodes.All(x => x.Code != code))
                    break;
            }

            return new Barcode(code);
        }

        private static string GenerateSecurityBarcode(MyContext context)
        {
            var randomizer = new Random();
            string code;

            var barcodes = context.Barcodes.ToList();

            while (true)
            {
                code = randomizer.Next(BarcodeConstants.PartMin,
                                       BarcodeConstants.PartMax)
                                       .ToString();

                if (barcodes.All(x => GetSecurityCode(x.Code) != code))
                    break;
            }

            return code;
        }

        public static string GetSecurityCode(string code)
        {
            // Take beginning and end * into consideration
            return code.Substring(BarcodeConstants.PartLength + 1, BarcodeConstants.PartLength);
        }

        public static Barcode GetValidBarcode(IEnumerable<Barcode> barcodes)
        {
            if (barcodes == null)
                return null;

            return barcodes.FirstOrDefault(
                b => !b.ExpirationDate.HasValue
                     || b.ExpirationDate.Value.Date <= DateTime.Today);
        }

        public static Barcode GetValidBarcode(this Guardian guardian)
        {
            return GetValidBarcode(guardian.Barcodes);
        }

        public static Barcode GetValidBarcode(this Kid kid)
        {
            return GetValidBarcode(kid.Barcodes);
        }

        public static string GetSecurityCode(this Guardian guardian)
        {
            return GetSecurityCode(guardian.GetValidBarcode().Code);
        }

        public static string GetSecurityCode(this Kid kid)
        {
            return GetSecurityCode(kid.GetValidBarcode().Code);
        }
    }
}